﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.Entity;
using System.Data.Entity.Core.Objects;
using System.Data.Entity.Infrastructure;
using SampleConsoleTest.Models;

namespace SampleConsoleTest
{
    class Program
    {
        static void Usage()
        {
            Console.WriteLine(
                "Usage: SampleConsoleTest.exe <Customer Email Address>");
        }

        //
        // If a data model class consists of a single encrypted string field, 
        // a hash of the plaintext value of that field is stored for each row.
        // This allows direct lookup.
        //
        // This helper function demonstrates the use of that feature. If an 
        // existing item isn't found, optionally, a new one is added.
        //
        private static Customer _GetCustomerObjInDb(
            SampleDataCtx dbCtx,
            string customerEmail, 
            bool canCreateNew)
        {
            Customer customerObjInDb = new Customer();
            byte[] thumbprintOfCustomer = customerObjInDb.GetThumbprint(
                customerEmail);
            customerObjInDb = (from c in dbCtx.Customers
                               where c.SecurEntityThumbprint == thumbprintOfCustomer
                               select c).FirstOrDefault();
            if (null == customerObjInDb && true == canCreateNew)
            {
                customerObjInDb = dbCtx.Customers.Create();
                customerObjInDb.SecurEntityThumbprint = thumbprintOfCustomer;
                customerObjInDb.EmailAddress = customerEmail;
                dbCtx.Customers.Add(customerObjInDb);
            }

            return customerObjInDb;
        }

        //
        // Command-line test entry point
        //
        static void Main(string[] args)
        {
            //
            // Check command-line
            //

            if (1 != args.Length)
            {
                Usage();
                return;
            }

            //
            // Ignore migration for this sample
            //

            Database.SetInitializer(
                new DropCreateDatabaseIfModelChanges<SampleDataCtx>());

            //
            // Setup the database context
            //

            SampleDataCtx dbCtx = new SampleDataCtx();

            //
            // Allow SecurEntity to add its callbacks
            //

            SecurEntityLib.DbContextHelper dch = 
                new SecurEntityLib.DbContextHelper(dbCtx);

            //
            // Find or create the specified customer
            //

            Customer customer = _GetCustomerObjInDb(dbCtx, args[0], true);

            //
            // Create a new order
            //

            Order newO = dbCtx.Orders.Create();
            newO.CreditCardNumber = "0000 0000 0000 0000";
            newO.Cust = customer;
            newO.Item = "Widgets";
            newO.Timestamp = DateTime.UtcNow;
            
            dbCtx.Orders.Add(newO);

            //
            // Read back all orders for this customer to demonstrate decryption.
            // Explicitly reference child POCO entities to ensure that they get
            // decrypted. 
            //
            // This query will only reference items already committed to the DB
            // (i.e. not including the new order just added above).
            //

            IQueryable<Order> orders = 
                from o in dbCtx.Orders.Include("Cust")
                where o.Cust.SecurEntityThumbprint == customer.SecurEntityThumbprint
                select o;

            List<Order> oList = orders.ToList();
            foreach (Order o in oList)
            {
                Console.WriteLine("{0} {1}", o.Cust.EmailAddress, o.Timestamp);
            }
            
            dbCtx.SaveChanges();
        }
    }
}